package com.mms.service.impl;


import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.mms.dao.IMedicalDao;
import com.mms.dao.IMedicalOfficeDao;
import com.mms.dao.IReserveDao;
import com.mms.enumerate.ReserveDiagnoseType;
import com.mms.enumerate.ReserveFlowProgress;
import com.mms.enumerate.ReserveWardType;
import com.mms.pojo.Medical;
import com.mms.pojo.Reserve;
import com.mms.pojo.UserInfo;
import com.mms.service.IReserveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * 预约表
 * </p>
 *
 * @author 陈林鹏
 * @since 2021-04-14
 */
@Service
public class ReserveServiceImpl extends ServiceImpl<IReserveDao, Reserve> implements IReserveService {

    /**
     * 预约表
     */
    @Autowired
    IReserveDao reserveDao;
    /**
     * 医务表
     */
    @Autowired
    IMedicalDao medicalDao;
    /**
     * 科室表
     */
    @Autowired
    IMedicalOfficeDao medicalOfficeDao;


    /**
     * 获取患者 结束的列
     *
     * @param patient
     * @return
     */
    public List<Map<String, Object>> completed(UserInfo patient) {
        return patientShow(patient, null, false,
                ReserveFlowProgress.appointments.getKey(),
                ReserveFlowProgress.processed.getKey());
    }

    public List<Map<String, Object>> patientShow(boolean be, Integer... key) {
        return patientShow(null, null, be, key);
    }

    @Override
    public List<Map<String, Object>> patientShow(Medical medical, boolean be, Integer... key) {
        return patientShow(null, medical, be, key);
    }

    public List<Map<String, Object>> patientShow(UserInfo patient
            , boolean be
            , Integer... key) {
        return patientShow(patient, null
                , be, key);
    }

    /**
     * 给病人显示预约表的数据界面
     * 获取病人的预约信息
     *
     * @param patient 可以是 patient = null
     * @param be      true is or false is and
     * @param key     可以是 key = null
     * @return
     */
    public List<Map<String, Object>> patientShow(UserInfo patient
            , Medical medical
            , boolean be
            , Integer... key) {

        List<Map<String, Object>> reserveS = null;
        if (key == null || key.length == 0) {
            //查询用户的预约记录 以及用户的信息
            reserveS = reserveDao.patientShow(patient
                    , medical
                    , be
                    , ReserveFlowProgress.appointments.getKey(),
                    ReserveFlowProgress.processed.getKey(),
                    ReserveFlowProgress.customs.getKey(),
                    ReserveFlowProgress.seeing.getKey());
        } else {
            reserveS = reserveDao.patientShow(patient
                    , medical
                    , be
                    , key);
        }
        for (Map<String, Object> aSingleData : reserveS) {
            try {
                //将diagnose_type 转换为 中文
                aSingleData.put("DIAGNOSE_TYPE",
                        ReserveDiagnoseType.getValueByKey(
                                Integer.parseInt(String.valueOf(aSingleData.get("DIAGNOSE_TYPE")))
                        ));
                //将flow_progress 转换为中文
                aSingleData.put("FLOW_PROGRESS",
                        ReserveFlowProgress.getValueByKey(
                                Integer.parseInt(String.valueOf(aSingleData.get("FLOW_PROGRESS")))
                        ));
                //将ward_type 转换为中文
                if (aSingleData.get("WARD_TYPE") != null) {
                    aSingleData.put("WARD_TYPE",
                            ReserveWardType.getValueByKey(
                                    Integer.parseInt(String.valueOf(aSingleData.get("WARD_TYPE")))
                            ));
                }
                //获取用户的预约记录的 医务信息
                Object medicalId = aSingleData.get("MEDICAL_ID");
                if (medicalId != null) {
                    aSingleData.put("Medical"
                            , medicalDao.selectById((Serializable) medicalId));
                }
                //获取用户的预约记录的 科室信息
                Object medicalOfficeId = aSingleData.get("MEDICAL_OFFICE_ID");
                if (medicalOfficeId != null) {
                    aSingleData.put("MedicalOffice"
                            , medicalOfficeDao.selectById((Serializable) medicalOfficeId));
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return reserveS;
    }

    /**
     * 用户预约
     *
     * @param userInfo 用户信息
     * @param reserve  预约信息
     * @return
     */
    public boolean makeAppointment(UserInfo userInfo, Reserve reserve) {
        //设置用户 ID
        reserve.setUserInfoId(userInfo.getId());
        //设置流程进度
        reserve.setFlowProgress(0);
        //设置创建用户名
        reserve.setCreateUsername(userInfo.getUsername());
        //插入数据
        Integer insert = reserveDao.insert(reserve);
        if (insert != null && insert > 0) {
            return true;
        }
        return false;
    }

    /**
     * 用户取消预约
     *
     * @param userInfo
     * @param reserveIds
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED
            , propagation = Propagation.REQUIRED
            , rollbackFor = Exception.class)
    public boolean cancelReservation(UserInfo userInfo, int[] reserveIds) {
        for (int reserveId : reserveIds) {
            if (!reserveDao
                    .setFlowProgress(reserveId
                            , ReserveFlowProgress.UserCancel.getKey()
                            , userInfo.getNickname())) {
                return false;
            }
        }
        return true;
    }

    /**
     * 医生接受预约
     *
     * @param medical
     * @param id
     * @return
     * @throws Exception
     */
    @Transactional(isolation = Isolation.READ_COMMITTED
            , propagation = Propagation.REQUIRED
            , rollbackFor = Exception.class)
    public boolean acceptAppointment(Medical medical, Integer[] id) throws Exception {
        for (Integer tempId : id) {
            //查询 预约信息
            Reserve reserve = selectById(tempId);
            //判断预约进度状态
            if (reserve.getFlowProgress() != ReserveFlowProgress.processed.getKey()) {
                //预约状态 非 待处理状态 抛出异常
                throw new Exception("禁止处理非待处理状态的预约");
            }
            //设置预约接受的主治医生
            reserve.setMedicalId(medical.getId());
            //设置预约进度 为预约成功
            reserve.setFlowProgress(ReserveFlowProgress.appointments.getKey());
            //设置最后修改日期
            reserve.setLastUpdateDate(new Date());
            //设置最后修改姓名
            reserve.setLastUpdateUsername(medical.getName());
            //更新数据
            updateById(reserve);
        }
        return true;
    }

    /**
     * 医生拒绝处理
     *
     * @param id
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED
            , propagation = Propagation.REQUIRED
            , rollbackFor = Exception.class)
    public void refuseProcessing(UserInfo userInfo, Integer[] id) throws Exception {
        for (Integer tempId : id) {
            //查询预约信息
            Reserve reserve = selectById(tempId);
            //如果查不到预约信息 抛出异常 并回滚 所有
            if (reserve == null) {
                throw new Exception("错误 查不到预约信息");
            }
            //设置预约信息 进度状态
            reserve.setFlowProgress(ReserveFlowProgress.appointment.getKey());
            reserve.setLastUpdateUsername(userInfo.getNickname());
            reserve.setLastUpdateDate(new Date());

            //更新预约数据表
            updateById(reserve);
        }
    }


}
